#ifndef _SERIAL_T_CHANNEL_H_
#define _SERIAL_T_CHANNEL_H_
/***********************************************************************
  *Copyright 2020-05-26, pyfree
  *
  *File Name       : serialtchannel.h
  *File Mark       : 
  *Summary         : 串口转发端接口实现
  *本接口模拟串口通信的从站端,会缓存串口各个地址的最新数值
  *在接收到上层应用的总召指令(查询)后,将按需将各个地址数值生成响应指令推送
  *在接收到上层应用的控制指令后,等待一段时间才从缓存读取匹配点的数值生成响应指令推送
  *Current Version : 1.00
  *Author          : pyfree
  *FinishDate      :
  *
  *Replace Version :
  *Author          :
  *FinishDate      :

 ************************************************************************/

#include "lib_acl.h"
#include "acl_cpp/lib_acl.hpp"

#include "tchannel.h"
#include "gsmmsg.h"
#include "conf_pmap.h"
#include "dtypedef.h"
#include "datadef.h"
#include "Mutex.h"

class UpdateThread;

struct PTO_STATE : public pyfree::PTo
{
    unsigned long rep_time;
    unsigned long taskID;
};

class SerialTChannel : public TranChannel,public acl::thread
{
public:
    /* 构造函数
     * @param tid_ {int} 转发口编号
	 * @return { } 
	 */
    SerialTChannel(int tid_);
    ~SerialTChannel();

    void* run();
    /**
	 * 更新串口数据,本串口作为从站端,会缓存所有地址的最新数值
	 * @return {void } 
	 */
    void updateData();
private:
    /* 本实例初始化
     * @param tid_ {int} 转发口编号
	 * @return {void } 
	 */
    void init(int tid_);
    /**
	 * 真正的打开串口实现
	 * @return {void } 
	 */
	bool startSms();
	/**
	 * 关闭串口
	 * @return {void } 
	 */
	void stopSms();
    /**
	 * 剖面数据更新
     * @param item {ChannelToTransmit} 采集口推送过来的业务数据
	 * @return {void } 
	 */
    bool serialDataUp(ChannelToTransmit item);
    /**
	 * 上层应用下发报文解析
	 * @param buf {char*} 报文指针
	 * @param len {int} 报文长度
	 * @return {int } <0时异常
	 */
    int AddFrameFromUp(const unsigned char *buf, int len); 
    /**
	 * 上层应用调度业务,当前版本只限定总召查询/单点查询/单点控制
	 * @param trans_ {QueueData} 业务集
	 * @return {void } 
	 */
    void dispatchFromUp(QueueData<TransmitToGChannel> trans_); 
    /**
	 * 总召响应处置
	 * @param taskID {ulong} 任务编号
	 * @return {void }
	 */
    void responseForAll(unsigned long taskID=0L,bool changeF=false);
    /**
	 * 指定开始地址查询响应处置
     * @param pid {unit} 点编号
     * @param psize {unit} 查询点数
	 * @param taskID {ulong} 任务编号
	 * @return {void }
	 */
    void responseForPonit(unsigned int pid, unsigned int psize=1, unsigned int respType=1,unsigned long taskID=0L);
    /**
	 * 根据信息点态势集合描述信息构建响应指令并推送上层应用
     * @param pinfo_vals_desc {string} 信息点态势集描述信息
	 * @param taskID {ulong} 任务编号
	 * @return {void }
	 */
    void sendCmd(std::string pinfo_vals_desc, unsigned int respType=1,unsigned long taskID=0L,bool changeF=false);
    /**
	 * 从信息点态势集合获取字符串描述信息
     * @param pinfos {map} 信息点态势集
	 * @param string {ret} 信息点态势集描述信息缓存
	 * @return {void }
	 */
    bool getInfoValDesc(std::map<int,float> pinfos,std::string &ret);
private:
    static float com_base_limit;        //浮点数比较限制值
    bool running;
    bool serial_open_flag;				//串口打开标识
    bool open_fail_log;                 //串打开日记标识,用于防止反复打开重复日志输出
    pyfree::SerialPort serialarg;		//串口定义
    gsmmsg m_ssg;						//真正的串口通信接口,采用ctb库实现
    unsigned long serial_data_ut;        //串口剖面数据全局时间点
    std::map<int,LiveData> serial_data; //串口剖面数据
    PYMutex serial_mutex;               //串口剖面数据锁
    std::list<PTO_STATE> response_point;  //被控制点,需要等待下层控制返回再进行上层响应
    PYMutex response_mutex;               //
    UpdateThread *ptr_UT;               //从缓存读取数据更新剖面数据
};


#endif 
